<template>
  <div class="table-adn-barline-marker-wrapper">
    <div class="content-wrapper">
      <div class="body-left">
        <Card>
          <div slot="title">
            <div class="filter-wrapper">
              <Button @click="showMeterDetail" type="warning" size="small">表具详情</Button>
            </div>
          </div>
          <div class="table-box">
            <Table
              ref="table"
              class="table-item"
              :height="tableHeight"
              :columns="tableColums"
              :loading="tableLoading"
              @on-row-click="onRowClickHandle"
              @on-row-dblclick="onRowDblclickHandle"
              :row-class-name="rowClassName"
              highlight-row
              size="small"
              :data="tableData"
            ></Table>
            <div class="page-box tc">
              <Page
                :total="tablePageData.total"
                size="small"
                simple
                @on-change="changeTablePageHandle"
                :page-size="tablaPageParams.pageSize"
              />
            </div>
          </div>
        </Card>
      </div>
      <div class="body-right">
        <div class="top-box">
          <Card>
            <div slot="title">
              <div class="filter-wrapper">
                <Button @click="handleHiddenLine" type="primary" size="small" style="margin-right:10px;">一键隐藏影线</Button>
                <Button @click="handleRollBack" type="info" size="small">还原隐藏</Button>
              </div>
            </div>
            <e-candlestick
              id="tableAndElineCandlestick"
              :chartData="candlestickData"
              @q-click="handleCandlClick"
              @q-contextmenu="handleCandlContextmenu"
            >
              <ul slot="right-menu" class="right-menu-list">
                <li class="right-menu-item item tc" @click="handleRightMenuClick">隐藏影线</li>
              </ul>
            </e-candlestick>
            <div class="no-data" v-show="showNoDataByCand">暂无数据</div>
            <Spin fix v-show="showCandlLoading">加载中...</Spin>
          </Card>
        </div>

        <div class="bottom-box">
          <div class="item">
            <Card>
              <h-bar3d id="bar3d-1" :chartData="firstBar3dData" :defaultOptions="hBar3dOptions" />
            </Card>
          </div>
          <div class="item">
            <Card>
              <h-bar3d id="bar3d-2" :chartData="lastBar3dData" :defaultOptions="hBar3dOptions" />
            </Card>
          </div>
          <div class="test-info">
            <Card :padding="5">
              <Row class="item">
                <i-col span="16" class="name" v-show="testInfo.precedingMonthName"
                  >{{ testInfo.precedingMonthName }}用气量:</i-col
                >
                <i-col span="8" class="text">{{ testInfo.precedingMonth }}</i-col>
              </Row>
              <Row class="item">
                <i-col span="16" class="name" v-show="testInfo.precedingMonthName"
                  >{{ testInfo.precedingMonthName }}有效数据:</i-col
                >
                <i-col span="8" class="text">{{ testInfo.precedingMonthSize }}</i-col>
              </Row>
              <Row class="item">
                <i-col span="16" class="name" v-show="testInfo.lastMonthName"
                  >{{ testInfo.lastMonthName }}用气量:</i-col
                >
                <i-col span="8" class="text">{{ testInfo.lastMonth }}</i-col>
              </Row>
              <Row class="item">
                <i-col span="16" class="name" v-show="testInfo.lastMonthName"
                  >{{ testInfo.lastMonthName }}有效数据:</i-col
                >
                <i-col span="8" class="text">{{ testInfo.lastMonthSize }}</i-col>
              </Row>
              <Row class="item">
                <i-col span="10" class="name" v-show="testInfo.msg">T检验结果:</i-col>
                <i-col span="14" class="text">{{ testInfo.msg }}</i-col>
              </Row>
            </Card>
            <div class="no-data" v-show="showNoDataByTest">暂无检测结果</div>
          </div>
          <Spin fix v-show="showTestInfoLoading">加载中...</Spin>
        </div>
      </div>
    </div>
    <Modal
      v-model="showKxianFlag"
      class="kxian-modal"
      title="详情"
      @on-cancel="onKxianCancel"
      width="96%"
      :styles="{ top: '30px', height: '85%' }"
    >
      <div class="chart-box">
        <div :is="detailComponent" :options="gasUseDetailOptions"></div>
      </div>
      <div slot="footer">
        <Button @click="onKxianCancel" ghost>关闭</Button>
      </div>
    </Modal>

    <!-- 表具详情 -->
    <Modal
      key="tableAndBarlineMeterDetailModal"
      v-model="showMeterDetailModalFlag"
      class="meter-detail-modal"
      title="详情"
      @on-cancel="meterDetailModalCancel"
      width="96%"
      :styles="{ top: '30px', height: '85%' }"
    >
      <div
        id="tableAndBarlineMeterDetail"
        :is="userAndMeterInfoTpl"
        :content="meterDetailData"
        :currentMeterId="currentMeterId"
      ></div>
      <div slot="footer">
        <Button @click="meterDetailModalCancel" ghost>关闭</Button>
      </div>
    </Modal>
  </div>
</template>
<script>
import dayjs from 'dayjs'
import minMax from 'dayjs/plugin/minMax'
import { each, isUndefined, last, merge, includes, indexOf, cloneDeep, some, isEmpty } from 'lodash'
import { getMeterUnitDetail } from '@/api/tableAndBarlineMarker'
import { tableData, getKxianData, getBar3dByTestData } from '@/api/linkRatioMonth'
import setTableHeightMixin from '@/mixins/setTableHeight'
import tableKeyUpToolMixin from '@/mixins/tableKeyUpTool'
import tableColums from './tableColums'
import { eCandlestickOptions, hBar3dOptions } from './chartOptions/index'

dayjs.extend(minMax)

export default {
  name: 'operateTable-month',
  mixins: [setTableHeightMixin, tableKeyUpToolMixin],
  props: {
    params: {
      type: Object
    }
  },
  components: {
    EchartBarlineMarker: () => import('@/commons/charts/EchartBarlineMarker'),
    ECandlestick: () => import('@/commons/charts/ECandlestick'),
    OperateECandlestickAndEline: () => import('@/commons/OperateECandlestickAndEline'),
    UserAndMeterDetailETree: () => import('@/commons/UserAndMeterDetailETree'),
    HBar3d: () => import('@/commons/charts/HBar3d')
  },
  data() {
    return {
      tableLoading: false,
      tableData: [],
      tablaPageParams: {
        pageNum: 1,
        pageSize: 20
      },
      tablePageData: {
        total: 0
      },
      rowTimer: null,
      selectedData: null,
      hasMoveFlag: false,
      showKxianFlag: false,
      gasUseDetailOptions: {
        meterId: null,
        month: null
      },
      detailComponent: null,
      candlestickData: null,
      candlestickDataBak: null,
      showMeterDetailModalFlag: false,
      meterDetailData: null,
      userAndMeterInfoTpl: null,
      showDetailLoading: false,
      currentMeterId: null,
      showNoDataByCand: false,
      firstBar3dData: null,
      lastBar3dData: null,
      testInfo: null,
      showCandlLoading: false,
      showTestInfoLoading: false,
      selectedCandlData: [],
      rightSelectedData: null,
      clearList: []
    }
  },
  watch: {
    selectedCandlData() {
      if (this.selectedCandlData.length === 2) {
        this.fetchBar3dData()
      }
    }
  },
  computed: {
    tableColums() {
      return tableColums
    },
    hBar3dOptions() {
      return hBar3dOptions
    },
    showNoDataByTest() {
      return isEmpty(this.testInfo)
    }
  },
  mounted() {
    this.fetchTableData()
  },
  beforeDestroy() {
    clearTimeout(this.rowTimer)
  },
  methods: {
    meterDetailModalCancel() {
      this.showMeterDetailModalFlag = false
      this.hasMoveFlag = false
      this.meterDetailData = null
      this.userAndMeterInfoTpl = null
    },
    /**
     * @msg: 表格中数据异常列突出显示
     * @param {type}
     * @return:
     */
    rowClassName(row = {}) {
      const { status } = row
      if (Number(status) === 1) {
        return 'row-abnormal'
      }
      return ''
    },
    /**
     * desc: k线图模态框取消
     * param {type}
     * return {type} void
     */
    onKxianCancel() {
      this.detailComponent = null
      this.showKxianFlag = false
      this.hasMoveFlag = false
    },
    /**
     * @msg: 选取当前选中的数据项
     * @param {type}
     * @return:
     */
    currentSelectedTableData() {
      const currentData = this.tableData[this.selectedIndex]
      this.selectedData = currentData
      const { meterId } = currentData
      this.currentMeterId = meterId
      this.fetchKxianData({
        meterId
      })
      this.fetchBar3dData()
    },
    /**
     * @msg: 表格页面修改
     * @param {type}
     * @return:
     */
    changeTablePageHandle(data) {
      this.tablaPageParams = {
        ...this.tablaPageParams,
        pageNum: data
      }
      this.$nextTick(() => {
        this.fetchTableData()
      })
    },
    /**
     * @msg: 表格行点击
     * @param {type}
     * @return:
     */
    onRowClickHandle(row, index) {
      const { meterId } = row
      this.currentMeterId = meterId
      this.selectedCandlData = []
      this.rightSelectedData = null
      this.clearList = []
      clearTimeout(this.rowTimer)
      this.rowTimer = setTimeout(() => {
        if (isUndefined(this.selectedIndex)) {
          this.dispatchEvent()
        }
        if (this.selectedIndex !== index) {
          this.selectedIndex = index
          this.hasKxianFetch = true
          this.$nextTick(() => {
            this.currentSelectedTableData()
          })
        }
      }, 300)
    },
    onRowDblclickHandle(row, index) {
      clearTimeout(this.rowTimer)
      const { currentDate = undefined } = this.params
      const { meterId } = row
      this.currentMeterId = meterId
      this.gasUseDetailOptions = {
        ...this.gasUseDetailOptions,
        meterId,
        month: currentDate
      }
      this.showKxianFlag = true
      this.hasMoveFlag = true
      this.detailComponent = 'OperateECandlestickAndEline'
    },
    /**
     * @msg: 这里表格数据
     * @param {type}
     * @return:
     */
    modifyTabelData(data = {}) {
      const { list = [], total, pageNum, pageSize } = data
      // 选中数据进来默认选中第一条数据
      list[0]._highlight = true
      this.tableData = list
      this.tablePageData = {
        ...this.tablePageData,
        total,
        pageSize,
        pageNum
      }
      const { meterId } = list[0]
      this.currentMeterId = meterId
      this.selectedIndex = 0
      let _timer = setInterval(() => {
        if (this.$refs.table) {
          this.setTableHeight()
          // 表格绑定键盘事件
          this.dispatchEvent()
          clearInterval(_timer)
          _timer = null
        }
      }, 200)
      this.$nextTick(() => {
        this.fetchKxianData({
          meterId
        })
        this.fetchBar3dData()
      })
    },
    /**
     * @msg: 获取表格数据
     * @param {type}
     * @return:
     */
    fetchTableData() {
      const { gasClass, ...rest } = this.params
      this.tableLoading = true
      tableData({
        ...this.tablaPageParams,
        ...rest,
        meterGasClass: gasClass,
        order: 'asc'
      })
        .then(res => {
          this.tableLoading = false
          if (res.date) {
            this.modifyTabelData(res.date)
          }
        })
        .catch(() => {
          this.tableLoading = false
        })
    },
    /**
     * @msg: 指数图数据
     * @param {type}
     * @return:
     */
    modifyRectTreeMapData(rawData = []) {
      let xAixisList = []
      let values = []
      const actualGas = []
      const markPointData = []
      each(rawData, item => {
        const [first, one, two, three, four, five] = item
        xAixisList.push(first)
        let color0 = '#ec0000'
        let borderColor0 = '#8A0000'
        let color = '#00da3c'
        let borderColor = '#008F28'
        const lastItem = last(item)
        if (lastItem) {
          color0 = '#ff9900'
          borderColor0 = '#ff9900'
          color = '#ff9900'
          borderColor = '#ff9900'
          markPointData.push({
            name: first,
            value: two,
            coord: [first, two],
            itemStyle: {
              color: '#ff9900'
            }
          })
        }
        if (five < 0) {
          color0 = '#ed141e'
          borderColor0 = '#ed141e'
          color = '#ed141e'
          borderColor = '#ed141e'
        }
        values.push({
          name: first,
          value: [one, two, four, three],
          itemStyle: {
            color,
            borderColor,
            borderColor0,
            color0
          }
        })
        actualGas.push(five)
      })

      return {
        xAixisList,
        values: {
          data: values,
          markPointData
        },
        actualGas
      }
    },
    /**
     * desc: 获取k线图数据
     * param {type}
     * return {type} void
     */
    fetchKxianData(params) {
      const { type } = this.params
      this.showNoDataByCand = false
      this.showCandlLoading = true
      getKxianData({
        ...params,
        type
      })
        .then(res => {
          if (res.date && res.date.length >= 0) {
            const { xAixisList, values, actualGas } = this.modifyRectTreeMapData(res.date)
            this.candlestickData = merge({}, eCandlestickOptions, {
              xAxis: {
                data: xAixisList
              },
              series: [
                {
                  data: values.data,
                  markPoint: {
                    data: values.markPointData
                  }
                },
                {
                  data: actualGas
                }
              ]
            })
            this.candlestickDataBak = values.data
          } else {
            this.candlestickData = null
            this.candlestickDataBak = null
            this.showNoDataByCand = true
          }
        })
        .finally(() => {
          this.showCandlLoading = false
        })
    },
    /**
     * @msg: 显示表具详情
     * @param {type}
     * @return:
     */
    showMeterDetail() {
      if (!this.currentMeterId) {
        return this.showWraningNotice('', '请选择数据后再操作')
      }
      this.showDetailLoading = true
      this.$Loading.start()
      getMeterUnitDetail(this.currentMeterId)
        .then(res => {
          this.showDetailLoading = false
          this.$Loading.finish()
          if (res.date) {
            this.meterDetailData = res.date
            this.userAndMeterInfoTpl = 'UserAndMeterDetailETree'
            this.showMeterDetailModalFlag = true
            this.hasMoveFlag = true
          }
        })
        .catch(e => {
          this.showDetailLoading = false
        })
    },
    /**
     * desc: 整理柱图数据
     * param {type}
     * return {type} void
     */
    modifyBar3dData(data = {}) {
      const { precedingMonth = [], lastMonth = [], tTest } = data
      const _firstCateList = []
      const _firstSerList = []
      const _lastCateList = []
      const _lastSerList = []

      each(precedingMonth, (item, index) => {
        const { min, max, count } = item
        const name = `${min}-${max}`
        _firstCateList.push(index)
        _firstSerList.push({
          name,
          y: count
        })
      })
      each(lastMonth, (item, index) => {
        const { min, max, count } = item
        const name = `${min}-${max}`
        _lastCateList.push(index)
        _lastSerList.push({
          name,
          y: count
        })
      })

      const { lastMonthName, precedingMonthName } = tTest

      this.firstBar3dData = merge({}, hBar3dOptions, {
        title: {
          text: precedingMonthName
        },
        xAxis: {
          categories: _firstCateList
        },
        series: [
          {
            data: _firstSerList
          }
        ]
      })
      this.lastBar3dData = merge({}, hBar3dOptions, {
        title: {
          text: lastMonthName
        },
        xAxis: {
          categories: _lastCateList
        },
        series: [
          {
            data: _lastSerList
          }
        ]
      })
      this.testInfo = tTest
    },
    /**
     * desc: 获取柱图数据
     * param {type}
     * return {type} void
     */
    fetchBar3dData() {
      this.showTestInfoLoading = true
      const [_one, _two] = this.selectedCandlData
      const _max = _one && dayjs.max(dayjs(_one), dayjs(_two)).format('YYYY-MM')
      const _min = _two && dayjs.min(dayjs(_one), dayjs(_two)).format('YYYY-MM')
      this.precedingMonth = _min || ''
      this.lastMonth = _max || ''
      getBar3dByTestData({
        meterId: this.currentMeterId,
        precedingMonth: _min,
        lastMonth: _max
      })
        .then(res => {
          if (res.date) {
            this.modifyBar3dData(res.date)
          }
        })
        .finally(() => {
          this.showTestInfoLoading = false
        })
    },
    /**
     * desc: K线图点击
     * param {type}
     * return {type} void
     */
    handleCandlClick(params = {}) {
      const {
        data: { name }
      } = params
      if (!includes(this.selectedCandlData, name)) {
        if (this.selectedCandlData.length < 2) {
          this.selectedCandlData.push(name)
        } else {
          return this.$Notice.warning({
            title: '提示信息',
            desc: '已经存在两条数据，请取消选中后再操作'
          })
        }
      } else {
        const _index = indexOf(this.selectedCandlData, name)
        if (~_index) {
          this.selectedCandlData.splice(_index, 1)
        }
      }
      // 选中数据，整理显示
      this.$nextTick(() => {
        this.modifyCandlDataBySelected()
      })
    },
    /**
     * desc: 处理选中数据
     * param {type}
     * return {type} void
     */
    modifyCandlDataBySelected() {
      const series = this.candlestickData.series ? cloneDeep(this.candlestickData.series) : []
      const _data = series[0] ? series[0].data : []
      each(_data, item => {
        const { name } = item
        if (this.selectedCandlData.length > 0) {
          if (includes(this.selectedCandlData, name)) {
            item.itemStyle.opacity = 0.2
          } else {
            item.itemStyle.opacity = 1
          }
        } else {
          item.itemStyle.opacity = 1
        }
      })
      series[0].data = _data
      this.candlestickData.series = series
    },
    /**
     * desc: 根据曲线获取k线图数据
     * param {type}
     * return {type} void
     */
    filterSerieDataByName(name) {
      const data = this.candlestickDataBak || []
      let _retData = null
      for (let i = 0; i < data.length; i++) {
        if (data[i].name === name) {
          _retData = data[i]
          break
        }
      }
      return _retData
    },
    /**
     * desc: 右键操作
     * param {type}
     * return {type} void
     */
    handleCandlContextmenu(params = {}) {
      const { data, seriesType, name } = params
      if (seriesType === 'line') {
        const _d = this.filterSerieDataByName(name)
        const { value, ...rest } = _d
        this.rightSelectedData = {
          ...rest,
          value: value
        }
      } else {
        const { value, ...rest } = data
        // eslint-disable-next-line no-unused-vars
        const [_one, ...list] = value
        this.rightSelectedData = {
          ...rest,
          value: list
        }
      }
    },
    /**
     * desc: 点击隐藏影线
     * param {type}
     * return {type} void
     */
    handleRightMenuClick() {
      if (this.filterClearData()) {
        return this.$Message.warning('此项数据已经进行过操作')
      }
      this.clearList.push(this.rightSelectedData)
      const data = this.candlestickData.series ? cloneDeep(this.candlestickData.series[0].data) : []
      const { name } = this.rightSelectedData
      const _nData = data.map(item => {
        if (item.name === name) {
          const [open, close] = item.value
          item.value = [open, close, close, open]
        }
        return item
      })
      this.candlestickData.series[0].data = _nData
    },
    /**
     * desc: 判断数据是否已经进行过隐藏影线操作
     * param {type}
     * return {type} 已经操作过范围true 反之false
     */
    filterClearData() {
      const { name } = this.rightSelectedData
      return some(this.clearList, { name })
    },
    /**
     * desc: 还原操作
     * param {type}
     * return {type} void
     */
    handleRollBack() {
      if (this.clearList.length === 0) {
        return this.$Notice.warning({
          title: '操作提示',
          desc: '没有可操作的数据'
        })
      }
      const data = this.candlestickDataBak ? cloneDeep(this.candlestickDataBak) : []
      const _nData = data.map(item => {
        if (this.clearList.length === 0) {
          return item
        }
        for (let i = 0; i < this.clearList.length; i++) {
          const { name, value } = this.clearList[i]
          if (item.name === name) {
            item.value = value
            this.clearList.splice(i, 1)
            break
          }
        }
        return item
      })
      this.candlestickData.series[0].data = _nData
    },
    /**
     * desc: 一键隐藏影线
     * param {type}
     * return {type} void
     */
    handleHiddenLine() {
      if (isEmpty(this.candlestickData)) {
        return this.$Notice.warning({
          title: '操作提示',
          desc: '没有可操作的数据'
        })
      }
      const _copyData = cloneDeep(this.candlestickDataBak)
      this.clearList = cloneDeep(this.candlestickDataBak)
      const _nData = _copyData.map(item => {
        const [open, close] = item.value
        item.value = [open, close, close, open]
        return item
      })
      this.candlestickData.series[0].data = _nData
    }
  }
}
</script>
<style lang="less" scoped>
@import './index.less';
</style>
